package action;

import global.Constants;
import global.beanUtils.BeanUtils;
import global.comparator.NameComparator;
import global.comparator.SizeComparator;
import global.comparator.TypeComparator;
import global.security.SessionUtils;

import java.io.File;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Random;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileItemFactory;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;

import service.NoteService;
import util.DateUtils;
import util.FileUtils;
import util.MessageUtils;
import util.ServletHelp;
import util.StringUtils;
import domain.Note;

/**
 * 笔记Action类.
 * <p>
 * 创建日期：2010-07-01<br>
 * 创建人：Xiyt<br>
 * 修改日期：<br>
 * 修改人：<br>
 * 修改内容：<br>
 * 
 * @author Xiyt
 * @version 1.0
 */
public class NoteAction extends BaseAction {

	/**
	 * 笔记Service
	 * */
	private NoteService noteService = null;

	/**
	 * @param noteService
	 *            the noteService to set
	 */
	public void setNoteService(NoteService noteService) {
		this.noteService = noteService;
	}


	/**
	 * 查询笔记列表
	 * @param ActionMapping
	 *            mapping
	 * @param ActionForm
	 *            form
	 * @param HttpServletRequest
	 *            request
	 * @param HttpServletResponse
	 *            response
	 * @return ActionForward
	 */
	@SuppressWarnings("unchecked")
	public ActionForward query(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		// 参数设定
		Map map = request.getParameterMap();
		Note paramNote = new Note();
		BeanUtils.populate(paramNote, map);

		// 取得笔记列表
		JSONArray datas = new JSONArray();
		List<Note> noteList = noteService.selectByCriteriaForPaging(paramNote);
		if(null!=noteList){
			datas = JSONArray.fromObject(noteList);
		}
		int count = noteService.countByCriteria(paramNote);

		// 返回结果
		JSONObject res = new JSONObject();
		res.put("success", true);
		res.put("datas", datas);
		res.put("results", count);
		ServletHelp.outRequestForJson(request, response, res.toString());
		return null;
	}


	/**
	 * 查询单个笔记
	 * @param ActionMapping
	 *            mapping
	 * @param ActionForm
	 *            form
	 * @param HttpServletRequest
	 *            request
	 * @param HttpServletResponse
	 *            response
	 * @return ActionForward
	 */
	public ActionForward getNote(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		// 笔记ID
		String noteId = request.getParameter("noteId");
		// 取得笔记分类
		Note note = noteService.selectByPrimaryKey(Integer.parseInt(noteId));

		// 返回结果
		JSONObject res = JSONObject.fromObject(note);
		res.put("success", true);
		ServletHelp.outRequestForJson(request, response, res.toString());
		return null;
	}

	/**
	 * 保存笔记
	 * @param ActionMapping
	 *            mapping
	 * @param ActionForm
	 *            form
	 * @param HttpServletRequest
	 *            request
	 * @param HttpServletResponse
	 *            response
	 * @return ActionForward
	 */
	@SuppressWarnings("unchecked")
	public ActionForward save(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		// 参数设定
		Map map = ServletHelp.getParameterMap(request);
		map.put("type", request.getParameter("type"));
		// 保存远程图片
		String savePath = ServletHelp.getRealPath(request,
				MessageUtils.setParamMessage(Constants.UPLOAD_PICTURE_PATH, new String[]{SessionUtils.getCurrentUserId()}));
		map.put("savePath", savePath);
		// 服务器名称
		String domain = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+request.getContextPath();
		map.put("domain", domain);

		// 保存笔记
		noteService.save(map);

		// 构造查询结果
		JSONObject res = new JSONObject();
		res.put("success", true);
		String result = res.toString();
		// 返回查询结果
		ServletHelp.outRequestForJson(request, response, result);
		return null;
	}

	/**
	 * 伦理删除笔记
	 * @param ActionMapping
	 *            mapping
	 * @param ActionForm
	 *            form
	 * @param HttpServletRequest
	 *            request
	 * @param HttpServletResponse
	 *            response
	 * @return ActionForward
	 */
	public ActionForward delete(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		// 笔记ID
		String noteIdStr = request.getParameter("noteIds");
		// 封装笔记列表
		if (StringUtils.isNotEmpty(noteIdStr)) {
			noteService.deleteNote(noteIdStr);
		}
		
		// 构造查询结果
		JSONObject res = new JSONObject();
		res.put("success", true);
		String result = res.toString();
		// 返回查询结果
		ServletHelp.outRequestForJson(request, response, result);
		return null;
	}

	/**
	 * 还原笔记
	 * @param ActionMapping
	 *            mapping
	 * @param ActionForm
	 *            form
	 * @param HttpServletRequest
	 *            request
	 * @param HttpServletResponse
	 *            response
	 * @return ActionForward
	 */
	public ActionForward returnNote(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		// 笔记ID
		String noteIdStr = request.getParameter("noteIds");
		// 封装笔记列表
		if (StringUtils.isNotEmpty(noteIdStr)) {
			noteService.returnNote(noteIdStr);
		}
		// 构造查询结果
		JSONObject res = new JSONObject();
		res.put("success", true);
		String result = res.toString();
		// 返回查询结果
		ServletHelp.outRequestForJson(request, response, result);
		return null;
	}

	/**
	 * 移动笔记
	 * @param ActionMapping
	 *            mapping
	 * @param ActionForm
	 *            form
	 * @param HttpServletRequest
	 *            request
	 * @param HttpServletResponse
	 *            response
	 * @return ActionForward
	 */
	public ActionForward move(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		// 笔记ID
		String noteIdStr = request.getParameter("noteIds");
		// 笔记分类ID
		String moveCategoryId = request.getParameter("moveCategoryId");
		// 封装笔记列表
		if (StringUtils.isNotEmpty(noteIdStr)
				&& StringUtils.isNotEmpty(moveCategoryId)) {
			// 移动笔记
			noteService.moveNote(noteIdStr, moveCategoryId);
		}
		// 构造查询结果
		JSONObject res = new JSONObject();
		res.put("success", true);
		String result = res.toString();
		// 返回查询结果
		ServletHelp.outRequestForJson(request, response, result);
		return null;
	}

	/**
	 * 清空笔记垃圾箱
	 * @param ActionMapping
	 *            mapping
	 * @param ActionForm
	 *            form
	 * @param HttpServletRequest
	 *            request
	 * @param HttpServletResponse
	 *            response
	 * @return ActionForward
	 */
	public ActionForward clear(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		// 笔记ID
		String noteIdStr = request.getParameter("noteIds");
		// 封装笔记列表
		if (StringUtils.isNotEmpty(noteIdStr)) {
			// 删除笔记
			noteService.deleteByNoteIds(noteIdStr);
		}

		// 构造查询结果
		JSONObject res = new JSONObject();
		res.put("success", true);
		String result = res.toString();
		// 返回查询结果
		ServletHelp.outRequestForJson(request, response, result);
		return null;
	}
	
	/**
	 * 发送笔记
	 * @param ActionMapping
	 *            mapping
	 * @param ActionForm
	 *            form
	 * @param HttpServletRequest
	 *            request
	 * @param HttpServletResponse
	 *            response
	 * @return ActionForward
	 */
	public ActionForward sendEmail(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		// 邮箱地址
		String emails = request.getParameter("emails");
		// 笔记ID
		String noteId = request.getParameter("noteId");

		// 发送笔记
		boolean hasSend = noteService.sendEmail(noteId, emails);

		// 构造查询结果
		JSONObject res = new JSONObject();
		if(hasSend){
			res.put("success", true);
		}else{
			res.put("success", false);
		}
		String result = res.toString();
		// 返回查询结果
		ServletHelp.outRequestForJson(request, response, result);
		return null;
	}
	
	/**
	 * 打印笔记
	 * @param ActionMapping
	 *            mapping
	 * @param ActionForm
	 *            form
	 * @param HttpServletRequest
	 *            request
	 * @param HttpServletResponse
	 *            response
	 * @return ActionForward
	 */
	public ActionForward print(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		// 笔记ID
		String noteId = request.getParameter("noteId");
		// 取得笔记分类
		Note note = noteService.selectByPrimaryKey(Integer.parseInt(noteId));
		
		// 文件名
		String fileName = Constants.TEMP_FILE_PATH +"/" + "printNote.html";
		// 文件的保存路径
		String filePath = ServletHelp.getRealPath(request, fileName);
		// 删除原有文件
		FileUtils.delete(filePath);
		// 创建新的打印临时文件
		String html = Constants.HTML_TEMPLET_START + "<center><h3>" + note.getTitle() + "</h3></center>" + note.getContent() + Constants.HTML_TEMPLET_END;
		FileUtils.createFileWithEncoder(filePath, html, "UTF-8");
		
		// 返回结果
		JSONObject res = JSONObject.fromObject(note);
		res.put("success", true);
		res.put("url", fileName);
		ServletHelp.outRequestForJson(request, response, res.toString());
		return null;
	}
	
	/**
	 * 上传笔记用图片
	 * @param ActionMapping
	 *            mapping
	 * @param ActionForm
	 *            form
	 * @param HttpServletRequest
	 *            request
	 * @param HttpServletResponse
	 *            response
	 * @return ActionForward
	 */
	@SuppressWarnings("unchecked")
	public ActionForward upload(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		// 初期化返回值对象
		response.setContentType("text/html; charset=UTF-8");
		JSONObject res = new JSONObject();
		res.put("success", true);
		res.put("error", 1);

		//文件保存目录路径
		String savePath = ServletHelp.getRealPath(request,
				MessageUtils.setParamMessage(Constants.UPLOAD_PICTURE_PATH, new String[]{SessionUtils.getCurrentUserId()}));
		//文件保存目录URL
		String saveUrl  = request.getContextPath() + MessageUtils.setParamMessage(Constants.UPLOAD_PICTURE_PATH, new String[]{SessionUtils.getCurrentUserId()});
		//定义允许上传的文件扩展名
		String[] fileTypes = new String[]{"gif", "jpg", "jpeg", "png", "bmp"};

		//创建日期文件夹
		String ymd = DateUtils.formatDate2Str(DateUtils.DATE_PATTON_3);
		savePath += "/" + ymd;
		saveUrl += "/" +ymd;
		File dirFile = new File(savePath);
		if (!dirFile.exists()) {
			dirFile.mkdirs();
		}

		//检查文件，并上传
		FileItemFactory factory = new DiskFileItemFactory();
		ServletFileUpload upload = new ServletFileUpload(factory);
		upload.setHeaderEncoding("UTF-8");
		List items = upload.parseRequest(request);
		Iterator itr = items.iterator();
		while (itr.hasNext()) {
			FileItem item = (FileItem) itr.next();
			String fileName = item.getName();
			if (!item.isFormField()) {
				//检查文件大小
				//最大文件大小
				long maxSize = 1000000;
				if(item.getSize() > maxSize){
					res.put("message", "上传文件大小超过限制。");
					response.getWriter().print(res.toString());
					return null;
				}
				//检查扩展名
				String fileExt = fileName.substring(fileName.lastIndexOf(".") + 1).toLowerCase();
				if(!Arrays.<String>asList(fileTypes).contains(fileExt)){
					res.put("message", "上传文件扩展名是不允许的扩展名。");
					response.getWriter().print(res.toString());
					return null;
				}
				//新文件名
				String newFileName = DateUtils.formatDate2Str(DateUtils.DATE_TIME_PATTON_3) + "_" + new Random().nextInt(1000) + "." + fileExt;
					
				File uploadedFile = new File(savePath, newFileName);
				item.write(uploadedFile);

				res.put("error", 0);
				res.put("url", saveUrl + "/" + newFileName);
				response.getWriter().print(res.toString());
				return null;
			}
		}
		return null;
	}
	
	/**
	 * 查看上传的图片
	 * @param ActionMapping
	 *            mapping
	 * @param ActionForm
	 *            form
	 * @param HttpServletRequest
	 *            request
	 * @param HttpServletResponse
	 *            response
	 * @return ActionForward
	 */
	@SuppressWarnings("unchecked")
	public ActionForward fileManager(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		//根目录路径，可以指定绝对路径，比如 /var/www/attached/
		String rootPath = ServletHelp.getRealPath(request,
				MessageUtils.setParamMessage(Constants.UPLOAD_PICTURE_PATH, new String[]{SessionUtils.getCurrentUserId()})) + "/";
		//根目录URL，可以指定绝对路径，比如 http://www.yoursite.com/attached/
		String rootUrl  = request.getContextPath() + MessageUtils.setParamMessage(Constants.UPLOAD_PICTURE_PATH, new String[]{SessionUtils.getCurrentUserId()}) + "/";
		//图片扩展名
		String[] fileTypes = new String[]{"gif", "jpg", "jpeg", "png", "bmp"};

		//根据path参数，设置各路径和URL
		String path = request.getParameter("path") != null ? request.getParameter("path") : "";
		String currentPath = rootPath + path;
		String currentUrl = rootUrl + path;
		String currentDirPath = path;
		String moveupDirPath = "";
		if (!"".equals(path)) {
			String str = currentDirPath.substring(0, currentDirPath.length() - 1);
			moveupDirPath = str.lastIndexOf("/") >= 0 ? str.substring(0, str.lastIndexOf("/") + 1) : "";
		}

		//排序形式，name or size or type
		String order = request.getParameter("order") != null ? request.getParameter("order").toLowerCase() : "name";

		File currentPathFile = new File(currentPath);
		//遍历目录取的文件信息
		List<Hashtable> fileList = new ArrayList<Hashtable>();
		if(currentPathFile.listFiles() != null) {
			for (File file : currentPathFile.listFiles()) {
				Hashtable<String, Object> hash = new Hashtable<String, Object>();
				String fileName = file.getName();
				if(file.isDirectory()) {
					hash.put("is_dir", true);
					hash.put("has_file", (file.listFiles() != null));
					hash.put("filesize", 0L);
					hash.put("is_photo", false);
					hash.put("filetype", "");
				} else if(file.isFile()){
					String fileExt = fileName.substring(fileName.lastIndexOf(".") + 1).toLowerCase();
					hash.put("is_dir", false);
					hash.put("has_file", false);
					hash.put("filesize", file.length());
					hash.put("is_photo", Arrays.<String>asList(fileTypes).contains(fileExt));
					hash.put("filetype", fileExt);
				}
				hash.put("filename", fileName);
				hash.put("datetime", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(file.lastModified()));
				fileList.add(hash);
			}
		}

		// 排序
		if ("size".equals(order)) {
			Collections.sort(fileList, new SizeComparator());
		} else if ("type".equals(order)) {
			Collections.sort(fileList, new TypeComparator());
		} else {
			Collections.sort(fileList, new NameComparator());
		}
		JSONObject result = new JSONObject();
		result.put("moveup_dir_path", moveupDirPath);
		result.put("current_dir_path", currentDirPath);
		result.put("current_url", currentUrl);
		result.put("total_count", fileList.size());
		result.put("file_list", fileList);

		// 返回结果
		JSONObject res = new JSONObject();
		res.put("success", true);
		ServletHelp.outRequestForJson(request, response, result.toString());
		return null;
	}
}
